/*
 * unittest4.c
 *
 *  Created on: Apr 27, 2014
 *      Author: chuaprar
 */

/*
 * Include the following lines in your makefile:
 *
 * unittest4: unittest4.c dominion.o rngs.o
 *      gcc -o unittest4 -g  unittest4.c dominion.o rngs.o $(CFLAGS)
 * -----------------------------------------------------------------------
 */

#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "rngs.h"
#include <stdlib.h>

#define TESTFUNC "scoreFor()"

int main() {
//int scoreFor (int player, struct gameState *state)
    int i, j, m;
    int seed = 1000;
    int numPlayers = 2;
    int thisPlayer = 0;
	struct gameState G;
	int k[10] = {adventurer, embargo, village, minion, mine, cutpurse,
			sea_hag, tribute, smithy, council_room};

	char* cardNames[] = {"curse", "estate", "duchy", "province", "great_hall", "gardens"};
	int scoreCards[] = {curse, estate, duchy, province, great_hall, gardens};
	int maxScoreCards[] = 	{30, 12, 12, 12, 12, 12};
	int rawScores[] = 		{-1, 1, 3, 6, 1, 0};
	int cardTypes = 6;
	int maxGarden = 12;

	printf("----------------- Testing: %s ----------------\n", TESTFUNC);

	// initialize a game state and player cards
	initializeGame(numPlayers, k, seed, &G);

	for (i=0; i<cardTypes-1; i++) {
		for (j=0; j<maxScoreCards[i]; j++) {

			// test hand cards
			G.handCount[thisPlayer] = j;
			G.deckCount[thisPlayer] = 0;
			G.discardCount[thisPlayer] = 0;
			for (m=0; m<=j; m++) {
				G.hand[thisPlayer][m] = scoreCards[i];
			}
			printf("handCount: %s count %d: score %d, expected %d\n", cardNames[i], j, scoreFor(thisPlayer, &G), rawScores[i]*j);
			assert(rawScores[i]*j == scoreFor(thisPlayer, &G));

			// test deck cards
			G.handCount[thisPlayer] = 0;
			G.deckCount[thisPlayer] = j;
			G.discardCount[thisPlayer] = 0;
			for (m=0; m<=j; m++) {
				G.deck[thisPlayer][m] = scoreCards[i];
			}
			printf("deckCount: %s count %d: score %d, expected %d\n", cardNames[i], j, scoreFor(thisPlayer, &G), rawScores[i]*j);
			printf("**TEST FAILS: assert commented out.  deckCount labeled as discardCount, double-counting discardCount **\n");
//			assert(rawScores[i]*j == scoreFor(thisPlayer, &G));

			// test discard cards
			G.handCount[thisPlayer] = 0;
			G.deckCount[thisPlayer] = 0;
			G.discardCount[thisPlayer] = j;
			for (m=0; m<=j; m++) {
				G.hand[thisPlayer][m] = scoreCards[i];
			}
			printf("discardCount: %s count %d: score %d, expected %d\n", cardNames[i], j, scoreFor(thisPlayer, &G), rawScores[i]*j);
			printf("**TEST FAILS: assert commented out. deckCount labeled as discardCount, double-counting discardCount **\n");
//			assert(rawScores[i]*j == scoreFor(thisPlayer, &G));
		}
	}

	// test for gardens
	for (i=5; i<50; i+=5) {

		if (i<12) maxGarden = i;
		else maxGarden = 12;

		// test for handCount
		G.handCount[thisPlayer] = i;
		G.deckCount[thisPlayer] = 0;
		G.discardCount[thisPlayer] = 0;


		// populate the mix of garden / non-garden cards
		for (j=0; j<maxGarden; j+=5) {
			for (m=0; m<=j; m++) {G.hand[thisPlayer][m] = gardens;}
			for (m=j+1; m<i; m++) {G.hand[thisPlayer][m] = copper;}

			printf("handCount: count %d gardencount %d score %d, expected %d\n", i, j, scoreFor(thisPlayer, &G), (i/10) * j);
			//assert(scoreFor(thisPlayer, &G) == (i/10) * j);
			printf("**TEST FAILS: assert commented out. fullDeckCount() not calc'd correctly for gardens**\n");
		}

		// test for handCount
		G.handCount[thisPlayer] = 0;
		G.deckCount[thisPlayer] = i;
		G.discardCount[thisPlayer] = 0;

		// populate the mix of garden / non-garden cards
		for (j=0; j<maxGarden; j+=5) {
			for (m=0; m<=j; m++) {G.deck[thisPlayer][m] = gardens;}
			for (m=j+1; m<i; m++) {G.deck[thisPlayer][m] = copper;}

			printf("deckCount: count %d gardencount %d score %d, expected %d\n", i, j, scoreFor(thisPlayer, &G), (i/10) * j);
			//assert(scoreFor(thisPlayer, &G) == (i/10) * j);
			printf("**TEST FAILS: assert commented out. fullDeckCount() not calc'd correctly for gardens**\n");
		}

		// test for discardCount
		G.handCount[thisPlayer] = 0;
		G.deckCount[thisPlayer] = 0;
		G.discardCount[thisPlayer] = i;

		// populate the mix of garden / non-garden cards
		for (j=0; j<maxGarden; j+=5) {
			for (m=0; m<=j; m++) {G.discard[thisPlayer][m] = gardens;}
			for (m=j+1; m<i; m++) {G.discard[thisPlayer][m] = copper;}

			printf("discardCount: count %d gardencount %d score %d, expected %d\n", i, j, scoreFor(thisPlayer, &G), (i/10) * j);
			//assert(scoreFor(thisPlayer, &G) == (i/10) * j);
			printf("**TEST FAILS: assert commented out. fullDeckCount() not calc'd correctly for gardens**\n");
		}
	}
    printf("\n >>>>> SUCCESS: Testing complete for %s <<<<<\n\n", TESTFUNC);

	return 0;
}
